#include "signalevent.h"
#include <unistd.h>
#include <string.h>
#include "log.h"

CSignalEvent::CSignalEvent(): m_pServer(NULL)
{
	::memset(m_pipefd, 0, sizeof(m_pipefd));
}
CSignalEvent::~CSignalEvent()
{
	m_pipefd[0] = 0;
	if (m_pipefd[1] > 0)
	{
		::close(m_pipefd[1]);
		m_pipefd[1] = 0;
	}
		
}

int CSignalEvent::Init()
{
	CPollerObject::EnableInput();

	return 0;
}

int CSignalEvent::create(void)
{
	if (::pipe(m_pipefd) < 0)
	{
		return -1;
	}

	netfd = m_pipefd[0];

	return 0;
}

int CSignalEvent::add(stEventItem* pitem)
{
	if (!pitem)
		return -1;

	if (!m_queue.enqueue(std::move(*pitem)))
	{
		log_error("enqueue err");
	}
	this->signal();

	return 0;
}

int CSignalEvent::signal(void)
{
	static char buff[1] = { 'a' };
	if (!(m_pipefd[1] > 0))
		return -1;

	int len = ::write(m_pipefd[1], buff, sizeof(buff));
	
	return (len > 0 ? 0 : -1);
}
int CSignalEvent::InputNotify(void)
{
	int ret = handinput();
	proc();

	return 0;
}

int CSignalEvent::proc(void)
{
	//int count = 0;
	bool found = false;
	do 
	{
		stEventItem item;
		found = m_queue.try_dequeue(item);
		if (found && m_pServer)
		{
			m_pServer->OnEventCallBack(&item);
		}
		//++count;
	} while (found && m_pServer);

	return 0;
}

int CSignalEvent::HangupNotify(void)
{
	log_error("hangup,fd,%d,%d", m_pipefd[0], m_pipefd[1]);

	return 0;
}

int CSignalEvent::handinput(void)
{
	char buff[100] = {'\0'};
	int len = ::read(netfd, buff, sizeof(buff) -1 );
	if (len > 0)
	{
		//log_debug("read,%d, data,%s", len, buff);
		return 0;
	}
	else if (-1 == len)
	{
		if (errno != EAGAIN && errno != EINTR && errno != EINPROGRESS)
		{
			log_warning("read failed from fd[%d], msg[%s]", netfd, strerror(errno));

			return -1;
		}

		return 0;
	}
	else
	{
		log_notice("closed by user fd[%d], msg[%s]", netfd, strerror(errno));

		return -1;
	}
}